package com.zf.yichat.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayFundTransToaccountTransferModel;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.request.AlipayFundTransToaccountTransferRequest;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayFundTransToaccountTransferResponse;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.aliyun.cloudauth20200618.Client;
import com.aliyun.cloudauth20200618.models.VerifyBankElementRequest;
import com.aliyun.cloudauth20200618.models.VerifyBankElementResponse;

import com.aliyun.tea.TeaException;
import com.aliyun.tea.TeaUnretryableException;
import com.aliyun.tearpc.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import com.google.common.collect.Maps;
import com.huifu.adapay.Adapay;
import com.huifu.adapay.model.MerConfig;
import com.huifu.adapay.model.Payment;
import com.zf.yichat.mapper.UserBankMapper;
import com.zf.yichat.mapper.UserMapper;
import com.zf.yichat.model.SysDict;
import com.zf.yichat.model.User;
import com.zf.yichat.model.UserBank;
import com.zf.yichat.model.UserTrade;
import com.zf.yichat.service.BalanceService;
import com.zf.yichat.service.PayService;
import com.zf.yichat.service.PushService;
import com.zf.yichat.service.SysDictService;
import com.zf.yichat.service.config.ConfigPay;
import com.zf.yichat.service.config.ConfigSet;
import com.zf.yichat.utils.HJpay.HjPayUtil;
import com.zf.yichat.utils.HJpay.com.sdk.entity.Response;
import com.zf.yichat.utils.HJpay.com.sdk.entity.WithdrawResponse;
import com.zf.yichat.utils.HJpay.com.sdk.utils.AESUtil;
import com.zf.yichat.utils.HJpay.com.sdk.utils.MD5Util;
import com.zf.yichat.utils.HJpay.com.sdk.utils.OkHttpUtil;
import com.zf.yichat.utils.HJpay.util.Md5_Sign;
import com.zf.yichat.utils.HJpay.HjWithdrawUtil;
import com.zf.yichat.utils.HttpProtocolHandler;
import com.zf.yichat.utils.XSpay.TransForm.Q001TransForm;
import com.zf.yichat.utils.XSpay.TransForm.R010TransForm;
import com.zf.yichat.utils.XSpay.TransForm.T003TransForm;
import com.zf.yichat.utils.XSpay.XSpayService;
import com.zf.yichat.utils.XmlUtils;
import com.zf.yichat.utils.YiChatMsgCode;
import com.zf.yichat.utils.common.*;
import com.zf.yichat.utils.response.FsResponse;
import com.zf.yichat.utils.response.FsResponseGen;
import com.zf.yichat.vo.BalanceType;
import com.zf.yichat.vo.DictKey;
import com.zf.yichat.vo.PayType;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.util.TextUtils;
import org.dom4j.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import sandpay.demo.FastPayApiUtil;
import sandpay.encrypt.EncryptUtil;
import sandpay.http.HttpUtil;
import sandpay.util.ConfigurationManager;
import sandpay2.cashier.sdk.CertUtil;
import sandpay2.cashier.sdk.HttpClient;
import sandpay2.cashier.sdk.SDKConfig;
import sandpay2.dsf.demo.AgentPayDemo;
import sandpay2.dsf.demo.DemoBase;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.zf.yichat.utils.HJpay.com.sdk.utils.RSAUtil.verify;

/**
 * 一句话描述功能
 *
 * @author yichat
 * @date create in 18:46 2019/8/14 2019
 */
@Service
public class PayServiceImpl implements PayService {


    private String prepay = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    private static Logger logger = LoggerFactory.getLogger(PayServiceImpl.class);

    @Autowired
    private BalanceService balanceService;
    @Autowired
    private PushService pushService;
    @Resource
    private UserBankMapper userBankMapper;

    @Resource
    private UserMapper userMapper;

    @Autowired
    private ConfigPay configPay;

    @Autowired
    private ConfigSet configSet;
    @Autowired
    private SysDictService sysDictService;

    @Override
    public Map<String, String> weixinPrePay(Long userId, Integer tradeType, BigDecimal money) {
        //暂时订单号使用
        String out_trade_no = DateUtils.formatDate(new Date(), "yyyyMMddHHmmssSSS") + userId;
        //生成交易记录
        balanceService.createTradeRecord(userId, out_trade_no, money, PayType.WEIXIN, tradeType);

        String body = "用户" + userId + "微信充值";

        String ip = "127.0.0.1";
        try {
            ip = InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }

        String response = HttpProtocolHandler.getInstance().doPostXml(prepay, XmlUtils.mapToXML(prePayParams(out_trade_no, money, GeneralUtils.getRandomStringByLength(16), configPay.getWeixin().getNotifyUrl(), ip, body)), "utf-8");

        String prePayId = getPrepayId(response);
        // pay params
        return StringUtils.isNoneBlank(prePayId) ? payParamsAPP(GeneralUtils.getRandomStringByLength(16), prePayId, out_trade_no) : null;
    }


    /**
     * 支付的参数列表-APP
     */
    private Map<String, String> payParamsAPP(String nonce_str, String prepayId, String outTradeNo) {
        Map<String, String> result = Maps.newHashMap(); // 调起支付 参数
        result.put("appid", configPay.getWeixin().getAppId()); // 微信开放平台审核通过的应用APPID
        result.put("partnerid", configPay.getWeixin().getMchId()); // 微信支付分配的商户号
        result.put("package", "Sign=WXPay"); // 扩展字段，暂填写固定值Sign=WXPay
        result.put("noncestr", nonce_str); //随机字符串，不长于32位。推荐随机数生成算法
        long time = System.currentTimeMillis();
        //mysq 时间戳只有10位 要做处理
        String dateline = time + "";
        dateline = dateline.substring(0, 10);
        result.put("timestamp", dateline); // 时间戳，请见接口规则-参数规定
        result.put("prepayid", prepayId);// 微信返回的支付交易会话ID
        result.put("sign", Sign.createSign(result, configPay.getWeixin().getAppKey()));// 签名
        return result;
    }


    private Map<String, String> prePayParams(String outTradeNo, BigDecimal totalFee, String nonce_str, String notifyUrl, String ip, String body) {
        Map<String, String> map = Maps.newHashMap();
        map.put("appid", configPay.getWeixin().getAppId());//微信开放平台审核通过的应用APPID
        map.put("mch_id", configPay.getWeixin().getMchId());//微信支付分配的商户号
        //        map.put("device_info", "WEB");//终端设备号(门店号或收银设备ID)，默认请传"WEB"
        map.put("nonce_str", nonce_str);//随机字符串，不长于32位。推荐随机数生成算法
        map.put("body", body);//商品描述交易字段格式根据不同的应用场景按照以下格式：APP——需传入应用市场上的APP名字-实际商品名称，天天爱消除-游戏充值。
        //        map.put("detail", "Ipad mini  16G  白色");//商品名称明细列表
        map.put("out_trade_no", outTradeNo);//商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号
        //        map.put("fee_type", "CNY");//符合ISO 4217标准的三位字母代码，默认人民币：CNY，其他值列表详见货币类型
        map.put("total_fee", totalFee.multiply(BigDecimal.valueOf(100)).longValue() + "");//订单总金额，单位为分，详见支付金额
        map.put("spbill_create_ip", ip);//用户端实际ip
        //String time = DateUtils.getBeijingTimeNow(YYYYMMDDHHMMSS);
        //map.put("time_start", time);
        //订单生成时间，格式为yyyyMMddHHmmss，如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则
        //map.put("time_expire", String.valueOf(Long.valueOf(time) + 30L * 60L + 1));
        // 订单失效时间，格式为yyyyMMddHHmmss，如2009年12月27日9点10分10秒表示为20091227091010。其他详见时间规则注意：最短失效时间间隔必须大于5分钟
        //        map.put("goods_tag", "WXG");//商品标记，代金券或立减优惠功能的参数，说明详见代金券或立减优惠
        //        map.put("notify_url", WeixinConfig.notifyUrl);
        map.put("notify_url", notifyUrl);
        //接收微信支付异步通知回调地址，通知url必须为直接可访问的url，不能携带参数。
        map.put("trade_type", "APP");//支付类型
        //        map.put("limit_pay", "no_credit");//no_credit--指定不能使用信用卡支付

        map.put("sign", Sign.createSign(map, configPay.getWeixin().getAppKey()));//签名，详见签名生成算法
        return map;
    }


    private String getPrepayId(String response) {
        try {
            logger.debug("微信统一下单返回结果: {}", response);
            Document document = DocumentHelper.parseText(response);
            Element root = document.getRootElement();
            Element returnCode = root.element("return_code");
            if ("SUCCESS".equals(returnCode.getText())) {
                Element resultCode = root.element("result_code");
                if ("SUCCESS".equals(resultCode.getText())) {
                    Element prepayId = root.element("prepay_id");
                    // pay params
                    return prepayId.getText();
                }
            }
        } catch (Exception e) {
            logger.error("解析微信统一下单返回结果失败", e);
        }
        logger.error("微信下单失败{}", response);
        return null;
    }

    private static final String WEIXIN_PAY_NOTIFY_END_WITH = "weixin pay notify: end with {}";

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String payNotify(String resXml) {

        String xmlBack = "";
        Map<String, String> map = null;

        boolean success = true;
        try {
            map = XmlUtils.xmlToMap(DocumentHelper.parseText(resXml));
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        if (logger.isDebugEnabled()) {
            logger.debug("weixin pay notify: {}", JSON.toJSONString(map));
        }
        // 交易结果
        String return_code = map.get("return_code");
        if (!"SUCCESS".equals(return_code)) {
            logger.warn(WEIXIN_PAY_NOTIFY_END_WITH, "返回code不是success");
            success = false;
        }
        // 签名验证
        /*String sign = map.get("sign");
        if (!Sign.signValidate(map, sign, appkey)) {
            logger.warn(WEIXIN_PAY_NOTIFY_END_WITH, "签名错误");
            success = false;
        }*/
        // 应用APPID
        String appid = map.get("appid");//微信开放平台审核通过的应用APPID
        if (!configPay.getWeixin().getAppId().equals(appid)) {
            logger.warn(WEIXIN_PAY_NOTIFY_END_WITH, "appId不匹配");
            success = false;
        }
        //商户号
        String mch_id = map.get("mch_id");//微信支付分配的商户号
        if (!configPay.getWeixin().getMchId().equals(mch_id)) {
            logger.warn(WEIXIN_PAY_NOTIFY_END_WITH, "ca商户号不匹配");
            success = false;
        }
        //交易类型
        String trade_type = map.get("trade_type");
        if (!"APP".equals(trade_type)) {
            logger.warn(WEIXIN_PAY_NOTIFY_END_WITH, "支付方式不匹配");
            success = false;
        }
        // 交易结果
        String result_code = map.get("result_code");//业务结果
        if (!"SUCCESS".equals(result_code)) {
            String err_code = map.get("err_code");//错误代码
            String err_code_des = map.get("err_code_des");//错误代码描述
            logger.warn("weixin pay notify: error_code {}", err_code);
            logger.warn("weixin pay notify: err_code_des {}", err_code_des);
            logger.warn(WEIXIN_PAY_NOTIFY_END_WITH, "支付失败");
            success = false;
        }

        if (!success) {
            return "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
        }

        //商户订单号
        String out_trade_no = map.get("out_trade_no");

        //查询交易记录
        UserTrade trade = balanceService.selectTradeByTradeNo(out_trade_no);
        if (Objects.isNull(trade) || trade.getStatus() == 1) {
            return "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
        }

        //金额入账
        balanceService.update(trade.getUserId(), trade.getType() == 0 ? BalanceType.ADD : BalanceType.WEIXIN_CREATE_PACKET, trade.getMoney(), trade.getId(), "微信充值");
        //交易记录状态更新
        balanceService.completeTrade(trade.getId());

        return "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";

    }

    private FsResponse xspayOpenAccount(User user, UserBank bank) {
//        UserBank bank = userBankMapper.selectByPrimaryKey(bankId);
//        if (Objects.isNull(bank)) {
//            return FsResponseGen.failMsg("银行卡不存在");
//        }
//        if (!userId.equals(bank.getUserId())) {
//            return FsResponseGen.failMsg("银行卡错误");
//        }
//
//        User user = userMapper.selectByPrimaryKey(userId);
        if (Objects.nonNull(user.getXspayuserid())) {
            return FsResponseGen.successData(user.getXspayuserid());
        }

        R010TransForm r010TransForm = new R010TransForm();
        r010TransForm.setTranCode("R010");
        r010TransForm.initCommonParams("R010", configPay.getxSpay().getMerId(), null);
        r010TransForm.setSubmitUrl("https://ncount.hnapay.com/api/r010.htm");
        r010TransForm.setMerUserId(String.valueOf(user.getId()));
        r010TransForm.setMobile(bank.getMobile());
        r010TransForm.setUserName(bank.getName());
        r010TransForm.setCertNo(bank.getIdNumber());

        try {
            Map<String, Object> result = XSpayService.getInstance().post(r010TransForm, R010TransForm.verifyArr);
            if (Objects.isNull(result)) {
                return FsResponseGen.failMsg("校验失败");
            }
            if ("0000".equals(result.get("resultCode"))) {
                String xsUserId = result.get("userId").toString();
                user.setXspayuserid(xsUserId);
//                user.setXspaybankid(bank.getId());
                userMapper.updateByPrimaryKeySelective(user);
                return FsResponseGen.successData(xsUserId);
            } else {
                return FsResponseGen.failMsg(result.get("errorMsg").toString());
            }
        } catch (Exception e) {
            e.printStackTrace();
            return FsResponseGen.failMsg("开户异常");
        }
    }

    @Override
    public FsResponse hjPayBindCardPre(Long userId, UserBank bank) {
        Example example = new Example(UserBank.class);
        example.createCriteria().andEqualTo("bankNumber", bank.getBankNumber()).andEqualTo("userId", userId);
        UserBank exist = userBankMapper.selectOneByExample(example);
        if (Objects.nonNull(exist)) {
            if (Objects.nonNull(exist.getHjbindcardno())) {
                if (exist.getStatus() == 1) {
                    exist.setStatus(0);
                    userBankMapper.updateByPrimaryKeySelective(exist);
                    return FsResponseGen.fail(YiChatMsgCode.BANK_DELETE_TO_ADD);
                } else {
                    return FsResponseGen.failMsg("银行卡已存在");
                }
            } else {
                bank.setId(exist.getId());
            }
        }

        User user = userMapper.selectByPrimaryKey(userId);
//        if (!user.getIdNumber().equals(bank.getIdNumber())) {
//            return FsResponseGen.failMsg("只能绑定自己名下的银行卡");
//        }

        ConfigPay.HJpay hjPay = configPay.gethJpay();
        String orderCode = userId + "bp" + DateUtils.formatDate(new Date(), "yyyyMMddHHmmss") + GeneralUtils.getRandomStringByLength(4);
        //汇聚支付
        Map<String, Object> map = new HashMap<>();
        map.put("mch_order_no", orderCode); // 商户订单号
        map.put("order_amount", "0.01"); // 订单金额
        map.put("mch_req_time", DateUtils.formatDate(new Date())); // 下单时间
        map.put("payer_name", AESUtil.Aes256Encode(bank.getName(), hjPay.getAesKey())); // 姓名
        map.put("id_type", "1"); // 证件类型
        map.put("id_no", AESUtil.Aes256Encode(bank.getIdNumber(), hjPay.getAesKey())); // 证件号码
        map.put("bank_card_no", AESUtil.Aes256Encode(bank.getBankNumber(), hjPay.getAesKey())); // 银行卡号
        map.put("mobile_no", AESUtil.Aes256Encode(bank.getMobile(), hjPay.getAesKey())); // 手机号
        try {
            String repStr = HjPayUtil.getHjResponse(hjPay.getPrivateKey(), hjPay.getAesKey(), hjPay.getPublicKey(), hjPay.getMerId(), hjPay.getRandStr(), map, HjPayUtil.METHOD_AGREEMENT_SIGN_SMS);
            JSONObject jsonObject = JSONObject.parseObject(repStr);
            String respCode = jsonObject.getString("resp_code");
            if ("SUCCESS".equals(respCode)) {
                String bizCode = jsonObject.getString("biz_code");
                if ("JS000000".equals(bizCode)) {
                    JSONObject resDataJson = jsonObject.getJSONObject("data");
                    if (!"P3000".equals(resDataJson.getString("order_status"))) {
                        return FsResponseGen.failMsg((String) resDataJson.getOrDefault("err_msg", resDataJson.getString("order_status")));
                    }
                    bank.setHjbindcardordercode(orderCode);
                    if (Objects.nonNull(bank.getId())) {
                        userBankMapper.updateByPrimaryKeySelective(bank);
                    } else {
                        userBankMapper.insertSelective(bank);
                    }
                    JSONObject resJ = new JSONObject();
                    resJ.put("merOrderId", orderCode);
                    resJ.put("ncountOrderId", orderCode);
                    return FsResponseGen.successData(resJ);
                } else {
                    return FsResponseGen.failMsg(jsonObject.getString("biz_msg"));
                }
            } else if ("FAIL".equals(respCode)) {
                return FsResponseGen.failMsg(jsonObject.getString("biz_msg"));
            } else {
                return FsResponseGen.failMsg(respCode);
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
            e.printStackTrace();
            return FsResponseGen.failMsg("支付异常");
        }
    }

//    public static void main(String[] args) {
//        try {
//         System.out.println(N3d.encode(212386L));
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        }
//    }

    @Override
    public FsResponse sandBindCard(Long userId, UserBank bank) {
        Example example = new Example(UserBank.class);
        example.createCriteria().andEqualTo("bankNumber", bank.getBankNumber()).andEqualTo("userId", userId);
        UserBank exist = userBankMapper.selectOneByExample(example);
        if (Objects.nonNull(exist)) {
            if (Objects.nonNull(exist.getHjbindcardno())) {
                if (exist.getStatus() == 1) {
                    exist.setStatus(0);
                    userBankMapper.updateByPrimaryKeySelective(exist);
                    return FsResponseGen.successData("绑卡成功");
                } else {
                    return FsResponseGen.failMsg("银行卡已存在");
                }
            } else {
                bank.setId(exist.getId());
            }
        }

        User user = userMapper.selectByPrimaryKey(userId);
        if (!user.getIdNumber().equals(bank.getIdNumber())) {
            return FsResponseGen.failMsg("只能绑定自己名下的银行卡");
        }
        if (!user.getRealName().equals(bank.getName())) {
            return FsResponseGen.failMsg("只能绑定自己名下的银行卡");
        }
        String orderCode = userId + System.currentTimeMillis() + "" + System.currentTimeMillis() + "1";

//           bank.setHjbindcardordercode(orderCode);
//           bank.setHjbindcardno(orderCode);
//           bank.setStatus(0);
//           if (Objects.nonNull(bank.getId())) {
//               userBankMapper.updateByPrimaryKeySelective(bank);
//           } else {
//               userBankMapper.insertSelective(bank);
//           }

        // 通过以下代码创建API请求并设置参数。
        VerifyBankElementRequest request = new VerifyBankElementRequest();
        // 场景ID。
        request.setSceneId(configSet.getAliyun().getSceneId());
        request.setOuterOrderNo(orderCode);
        request.setMode("VERIFY_BANK_CARD");
        request.setIdName(bank.getName());

        request.setIdNo(bank.getIdNumber());
        //  request.setMobile(bank.getMobile());
        request.setBankCardNo(bank.getBankNumber());
        //  request.setBankCardUrl(银行卡证件http、https地址);

        //  推荐，支持服务路由。
        VerifyBankElementResponse response = bankElementSmartVerifyAutoRoute(request);
        if (response != null) {
            String code = response.getCode();
            if ("200".equals(code)) {
                String passed = response.getResultObject().getPassed();
                if ("T".equals(passed)) {
                    bank.setHjbindcardordercode(orderCode);
                    bank.setHjbindcardno(orderCode);
                    bank.setStatus(0);
                    if (Objects.nonNull(bank.getId())) {
                        userBankMapper.updateByPrimaryKeySelective(bank);
                    } else {
                        userBankMapper.insertSelective(bank);
                    }
                    return FsResponseGen.successData("绑卡成功");

                }else{
                    String msg=response.getMessage();
                    if(TextUtils.isEmpty(msg)){
                        msg="绑卡要素不匹配";

                    }

                    return FsResponseGen.failMsg(msg);
                }
            }else{
                String msg=response.getMessage();
                if(TextUtils.isEmpty(msg)){
                    msg="服务商响应失败";

                }

                return FsResponseGen.failMsg(msg);

            }
        }else {
            return FsResponseGen.failMsg("绑卡检验服务商返回失败");

        }

 




    }

    @Override
    public FsResponse bindCardUu(Long userId, UserBank bank) {
        Example example = new Example(UserBank.class);
        example.createCriteria().andEqualTo("bankNumber", bank.getBankNumber()).andEqualTo("userId", userId);
        UserBank exist = userBankMapper.selectOneByExample(example);
        if (Objects.nonNull(exist)) {
             if (exist.getStatus() == 1) {
                 exist.setStatus(0);
                 userBankMapper.updateByPrimaryKeySelective(exist);
                 return FsResponseGen.successData("绑定成功");
             } else {
                 return FsResponseGen.failMsg("该钱包地址已存在");
             }
        }
        String orderCode = userId + System.currentTimeMillis() + "" + System.currentTimeMillis() + "1";
        bank.setHjbindcardordercode(orderCode);
        bank.setHjbindcardno(orderCode);
        bank.setStatus(0);
        if (Objects.nonNull(bank.getId())) {
            userBankMapper.updateByPrimaryKeySelective(bank);
        } else {
            userBankMapper.insertSelective(bank);
        }
        return FsResponseGen.successData("设置成功");




    }


    private VerifyBankElementResponse bankElementSmartVerifyAutoRoute(VerifyBankElementRequest request) {
        // 第一个为主区域Endpoint，第二个为备区域Endpoint。
        List<String> endpoints = Arrays.asList("cloudauth.cn-shanghai.aliyuncs.com", "cloudauth.cn-beijing.aliyuncs.com");
        VerifyBankElementResponse lastResponse = null;
        for (String endpoint : endpoints) {
            try {
                VerifyBankElementResponse response = bankElementSmartVerify(endpoint, request);
                lastResponse = response;

                // 服务端错误，切换到下个区域调用。
                if (response != null && "500".equals(response.getCode())) {
                    continue;
                }

                return response;
            } catch (Exception e) {
                // 网络异常，切换到下个区域调用。
                if (e.getCause() instanceof TeaException) {
                    TeaException teaException = ((TeaException) e.getCause());
                    if (teaException.getData() != null && "ServiceUnavailable".equals(
                            teaException.getData().get("Code"))) {
                        continue;
                    }
                }

                if (e.getCause() instanceof TeaUnretryableException) {
                    continue;
                }
            }
        }

        return lastResponse;
    }

    private VerifyBankElementResponse bankElementSmartVerify(String endpoint, VerifyBankElementRequest request)
            throws Exception {
        // 通过以下代码创建Config实例并初始化。
        Config config = new Config();
        // 您的AccessKey ID。
        config.setAccessKeyId(configSet.getAliyun().getAccessKeyID());
        config.setAccessKeySecret(configSet.getAliyun().getAccessKeySecret());
        // 设置您的Endpoint。
        config.setEndpoint(endpoint);
        // 设置https代理。
        //config.setHttpsProxy(https://xx.xx.xx.xx:xxxx);
        // 设置http代理。
        //config.setHttpProxy(http://xx.xx.xx.xx:xxxx);
        Client client = new Client(config);

        // 创建RuntimeObject实例并设置运行参数。
        RuntimeOptions runtime = new RuntimeOptions();
        // 设置调用超时时间（单位ms）。
        runtime.readTimeout = 10000;
        // 设置连接超时时间（单位ms）。
        runtime.connectTimeout = 10000;
        // 设置是否自动重试。
        runtime.autoretry = false;

        return client.verifyBankElement(request, runtime);
    }

    @Override
    public FsResponse hjPayBindCardConfirm(String orderCode, String ncountOrderId, String smsCode) {
        ConfigPay.HJpay hjPay = configPay.gethJpay();
        //汇聚支付
        Map<String, Object> map = new HashMap<>();
        map.put("mch_order_no", orderCode); // 商户订单号
        map.put("sms_code", smsCode); // 银行卡号
        try {
            String repStr = HjPayUtil.getHjResponse(hjPay.getPrivateKey(), hjPay.getAesKey(), hjPay.getPublicKey(), hjPay.getMerId(), hjPay.getRandStr(), map, HjPayUtil.METHOD_AGREEMENT_SIGN);
            JSONObject jsonObject = JSONObject.parseObject(repStr);
            String respCode = jsonObject.getString("resp_code");
            if ("SUCCESS".equals(respCode)) {
                String bizCode = jsonObject.getString("biz_code");
                if ("JS000000".equals(bizCode)) {
                    JSONObject resDataJson = jsonObject.getJSONObject("data");
                    if (!"P1000".equals(resDataJson.getString("order_status"))) {
                        return FsResponseGen.failMsg((String) resDataJson.getOrDefault("err_msg", resDataJson.getString("order_status")));
                    }
                    Example example = new Example(UserBank.class);
                    example.createCriteria().andEqualTo("hjbindcardordercode", orderCode);
                    UserBank bank = userBankMapper.selectOneByExample(example);
                    bank.setHjbindcardno(resDataJson.getString("sign_no"));
                    userBankMapper.updateByPrimaryKeySelective(bank);
                    return FsResponseGen.successData(orderCode);
                } else {
                    return FsResponseGen.failMsg(jsonObject.getString("biz_msg"));
                }
            } else if ("FAIL".equals(respCode)) {
                return FsResponseGen.failMsg(jsonObject.getString("biz_msg"));
            } else {
                return FsResponseGen.failMsg(respCode);
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
            e.printStackTrace();
            return FsResponseGen.failMsg("支付异常");
        }
    }

    @Override
    public FsResponse hjPayPre(String orderCode, Long userId, Integer tradeType, BigDecimal money, Integer bankId) {
        if (money.compareTo(BigDecimal.ZERO) <= 0) {
            return FsResponseGen.failMsg("金额必须大于0");
        }
        UserBank bank = userBankMapper.selectByPrimaryKey(bankId);
        if (Objects.isNull(bank)) {
            return FsResponseGen.failMsg("银行卡不存在");
        }
        if (!userId.equals(bank.getUserId())) {
            return FsResponseGen.failMsg("银行卡错误");
        }
        //生成交易记录
        balanceService.createTradeRecord(userId, orderCode, money, PayType.XSPAY, tradeType);
        ConfigPay.HJpay hjPay = configPay.gethJpay();
        //汇聚支付
        Map<String, Object> map = new HashMap<>();
        map.put("mch_order_no", orderCode); // 商户订单号
        map.put("order_amount", String.valueOf(NumberUtils.halfTwo(money))); // 订单金额
        map.put("mch_req_time", DateUtils.formatDate(new Date())); // 下单时间
        map.put("order_desc", "用户" + userId + "购买商品"); // 下单时间
        map.put("callback_url", hjPay.getNotifyUrl()); // 下单时间
        map.put("bank_card_no", AESUtil.Aes256Encode(bank.getBankNumber(), hjPay.getAesKey())); // 银行卡号
        try {
            String repStr = HjPayUtil.getHjResponse(hjPay.getPrivateKey(), hjPay.getAesKey(), hjPay.getPublicKey(), hjPay.getMerId(), hjPay.getRandStr(), map, HjPayUtil.METHOD_AGREEMENT_PAY_SMS);
            JSONObject jsonObject = JSONObject.parseObject(repStr);
            String respCode = jsonObject.getString("resp_code");
            if ("SUCCESS".equals(respCode)) {
                String bizCode = jsonObject.getString("biz_code");
                if ("JS000000".equals(bizCode)) {
                    JSONObject resDataJson = jsonObject.getJSONObject("data");
                    if (!"P3000".equals(resDataJson.getString("order_status"))) {
                        return FsResponseGen.failMsg((String) resDataJson.getOrDefault("err_msg", resDataJson.getString("order_status")));
                    }
                    JSONObject resJ = new JSONObject();
                    resJ.put("merOrderId", orderCode);
                    resJ.put("ncountOrderId", orderCode);
                    return FsResponseGen.successData(resJ);
                } else {
                    return FsResponseGen.failMsg(jsonObject.getString("biz_msg"));
                }
            } else if ("FAIL".equals(respCode)) {
                return FsResponseGen.failMsg(jsonObject.getString("biz_msg"));
            } else {
                return FsResponseGen.failMsg(respCode);
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
            e.printStackTrace();
            return FsResponseGen.failMsg("支付异常");
        }
    }

    @Override
    public FsResponse hjPayConfirm(String orderCode, String ncountOrderId, String smsCode) {
        ConfigPay.HJpay hjPay = configPay.gethJpay();
        //汇聚支付
        Map<String, Object> map = new HashMap<>();
        map.put("mch_order_no", orderCode); // 商户订单号
        map.put("mch_req_time", DateUtils.formatDate(new Date())); // 下单时间
        map.put("sms_code", smsCode); // 下单时间
        try {
            String repStr = HjPayUtil.getHjResponse(hjPay.getPrivateKey(), hjPay.getAesKey(), hjPay.getPublicKey(), hjPay.getMerId(), hjPay.getRandStr(), map, HjPayUtil.METHOD_AGREEMENT_PAY);
            JSONObject jsonObject = JSONObject.parseObject(repStr);
            String respCode = jsonObject.getString("resp_code");
            if ("SUCCESS".equals(respCode)) {
                String bizCode = jsonObject.getString("biz_code");
                if ("JS000000".equals(bizCode)) {
                    JSONObject resDataJson = jsonObject.getJSONObject("data");
                    if ("P2000".equals(resDataJson.getString("order_status"))) {
                        return FsResponseGen.failMsg((String) resDataJson.getOrDefault("err_msg", resDataJson.getString("order_status")));
                    }
                    return FsResponseGen.success();
                } else {
                    return FsResponseGen.failMsg(jsonObject.getString("biz_msg"));
                }
            } else if ("FAIL".equals(respCode)) {
                return FsResponseGen.failMsg(jsonObject.getString("biz_msg"));
            } else {
                return FsResponseGen.failMsg(respCode);
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
            e.printStackTrace();
            return FsResponseGen.failMsg("支付异常");
        }
    }

    @Override
    public FsResponse sandWithDraw(Integer id, Long userId, String bankNumber, BigDecimal money) {
//        User user = userMapper.selectByPrimaryKey(userId);
//        if (Objects.isNull(user.getXspayuserid())) {
//            return FsResponseGen.failMsg("未开户，请使用最新版app进行提现");
//        }
        Example example = new Example(UserBank.class);
        example.createCriteria().andEqualTo("userId", userId).andEqualTo("bankNumber", bankNumber).andEqualTo("status", 0);
        UserBank bank = userBankMapper.selectOneByExample(example);
        if (Objects.isNull(bank)) {
            return FsResponseGen.failMsg("未找到银行卡");
        }
//        if (Objects.isNull(bank.getXsbindcardagrno())) {
//            return FsResponseGen.failMsg("未绑卡");
//        }
        if (money.compareTo(BigDecimal.ZERO) <= 0) {
            return FsResponseGen.failMsg("提现金额小于0");
        }

        AgentPayDemo demo = new AgentPayDemo();
        String reqAddr = "agentpay";   //接口报文规范中获取

        //加载配置文件
        SDKConfig.getConfig().loadPropertiesFromSrc();
        //加载证书
        try {
            CertUtil.init(SDKConfig.getConfig().getSandCertPath(), SDKConfig.getConfig().getSignCertPath(), SDKConfig.getConfig().getSignCertPwd());
            String moneyString = String.valueOf(money.multiply(new BigDecimal("100")).intValue());
            int length = moneyString.length();
            for (int i = 0; i < (12 - length); i++) {
                moneyString = "0" + moneyString;
            }
            //设置报文
            demo.setRequest(moneyString, bank.getBankNumber(), bank.getName());

            String merId = SDKConfig.getConfig().getMid();            //商户ID
            String plMid = SDKConfig.getConfig().getPlMid();        //平台商户ID

            JSONObject resp = DemoBase.requestServer(demo.request, reqAddr, DemoBase.AGENT_PAY, merId, plMid);
            logger.error("提现处理结果====》" + resp);
            if (resp != null) {
                if (resp.getString("resultFlag").equals("0")) {
                    balanceService.checkWithdrawForHj(id, 1, null);
                    FsResponseGen.success();
                } else {
                    balanceService.checkWithdrawForHj(id, 2, "提现异常，请联系客服处理");
                    return FsResponseGen.failMsg("受理失败，请联系客服处理");
                }


//                logger.info("响应码：["+resp.getString("respCode")+"]");
//                logger.info("响应描述：["+resp.getString("respDesc")+"]");
//                logger.info("处理状态：["+resp.getString("resultFlag")+"]");
//
//                System.out.println("响应码：["+resp.getString("respCode")+"]");
//                System.out.println("响应描述：["+resp.getString("respDesc")+"]");
//                System.out.println("处理状态：["+resp.getString("resultFlag")+"]");
            } else {
                return FsResponseGen.failMsg("受理失败，请联系客服处理");
//                logger.error("服务器请求异常！！！");
//                System.out.println("服务器请求异常！！！");
            }


        } catch (Exception e) {
            e.printStackTrace();
            return FsResponseGen.failMsg("受理失败，请联系客服处理");
        }
        return FsResponseGen.success();


//        String orderCode = id + "_" + userId + "_" + userId;
//        ConfigPay.HJpay hJpay = configPay.gethJpay();
//        Map<String, Object> map = new HashMap<>();
//        map.put("userNo", hJpay.getMerId());// 商户编号
//        map.put("productCode", "BANK_PAY_DAILY_ORDER");//产品类型
//        map.put("requestTime", DateUtils.formatDate(new Date())); // 交易请求时间
//        map.put("merchantOrderNo", orderCode);//商户订单号
//        map.put("receiverAccountNoEnc", bank.getBankNumber()); // 收款账户号
//        map.put("receiverNameEnc", bank.getName()); // 收款人
//        map.put("receiverAccountType", "201");//账户类型
//        map.put("paidAmount", NumberUtils.halfTwo(money)); //交易金额
//        map.put("currency", "201");//币种
//        map.put("isChecked", "202");//是否复核
//        map.put("paidDesc", "用户提现");//代付说明
//        map.put("paidUse", "207");//代付用途
//        map.put("callbackUrl", hJpay.getNotifyWithdrawUrl());//代付用途
//        try {
//            String respStr = HjWithdrawUtil.getHjResponse(hJpay.getMd5Key(), map);
//            Map<String, Object> httpResponseMap = (Map<String, Object>) JSONObject.parse(respStr);
//            Integer statusCode = (Integer) httpResponseMap.get("statusCode");
//            if (2001 == statusCode) {
////                return FsResponseGen.success();
//            } else if (2002 == statusCode) {
//                logger.error("受理失败:{}", respStr);
//                return FsResponseGen.failMsg("受理失败，请联系客服处理");
//            } else {
//                logger.error("withdraw may err:{}", id);
////                return FsResponseGen.success();
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//            logger.error("withdraw err:{}", e.getMessage());
////            return FsResponseGen.failMsg("提现异常");
//        }
//        return FsResponseGen.success();
    }


    @Override
    public FsResponse hjPayWithDraw2(Integer id, Long userId, String bankNumber, BigDecimal money) {
//        User user = userMapper.selectByPrimaryKey(userId);
//        if (Objects.isNull(user.getXspayuserid())) {
//            return FsResponseGen.failMsg("未开户，请使用最新版app进行提现");
//        }
        Example example = new Example(UserBank.class);
        example.createCriteria().andEqualTo("userId", userId).andEqualTo("bankNumber", bankNumber).andEqualTo("status", 0);
        UserBank bank = userBankMapper.selectOneByExample(example);
        if (Objects.isNull(bank)) {
            return FsResponseGen.failMsg("未找到银行卡");
        }
//        if (Objects.isNull(bank.getXsbindcardagrno())) {
//            return FsResponseGen.failMsg("未绑卡");
//        }
        if (money.compareTo(BigDecimal.ZERO) <= 0) {
            return FsResponseGen.failMsg("提现金额小于0");
        }


        String orderCode = id + "_" + userId + "_" + userId;
        ConfigPay.HJpay hJpay = configPay.gethJpay();
        Map<String, Object> map = new HashMap<>();
        map.put("userNo", hJpay.getMerId());// 商户编号
        map.put("productCode", "BANK_PAY_DAILY_ORDER");//产品类型
        map.put("requestTime", DateUtils.formatDate(new Date())); // 交易请求时间
        map.put("merchantOrderNo", orderCode);//商户订单号
        map.put("receiverAccountNoEnc", bank.getBankNumber()); // 收款账户号
        map.put("receiverNameEnc", bank.getName()); // 收款人
        map.put("receiverAccountType", "201");//账户类型
        map.put("paidAmount", NumberUtils.halfTwo(money)); //交易金额
        map.put("currency", "201");//币种
        map.put("isChecked", "202");//是否复核
        map.put("paidDesc", "用户提现");//代付说明
        map.put("paidUse", "207");//代付用途
        map.put("callbackUrl", hJpay.getNotifyWithdrawUrl());//代付用途
        try {
            String respStr = HjWithdrawUtil.getHjResponse(hJpay.getMd5Key(), map);
            Map<String, Object> httpResponseMap = (Map<String, Object>) JSONObject.parse(respStr);
            Integer statusCode = (Integer) httpResponseMap.get("statusCode");
            if (2001 == statusCode) {
//                return FsResponseGen.success();
            } else if (2002 == statusCode) {
                logger.error("受理失败:{}", respStr);
                return FsResponseGen.failMsg("受理失败，请联系客服处理");
            } else {
                logger.error("withdraw may err:{}", id);
//                return FsResponseGen.success();
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("withdraw err:{}", e.getMessage());
//            return FsResponseGen.failMsg("提现异常");
        }
        return FsResponseGen.success();
    }


    public static void main2(String[] args) {
        String rsaPri = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAKH2O7ZuCZjQTJccz07RU/+4edEmHYvERJmUelL9pdA5KEkywccXPKdGT0KwdewN8cMbUAD47sDDq09qhpjqpfGJCYR7xOpO57e4QwauU4fwbkJhG98+CTy9STPB7uTYENp7T159NQ4l3218eWUAzEtn0ZMOuWMN6u8E52tfPzMTAgMBAAECgYAMiNH2PG3htb03tLMWlny5vb0vwpNmzbnBaQxOf/LlOoczown8LoAzMe3Qa3e03R9oyiRW7u0LXhlT/BqOmxpch4F8ACFDfRDBLKljB4NZoijOfxAlonS+HOQ3J4Mgb6XLf1LOqNSMy7E2wbt6jzhNDZzv6i2lgcjJVWWVbgvxgQJBANUtM8dErBY0iUpW+i80qYavxSQB1dOsougmXnaV/+8ml0/beIQ7YJYaS5O0f1gqLgB++K2/5sbqxvb0k/gqkccCQQDCf0SCkdO02gianOwl9z1tqKbVzRSXD9pbE0j+G+zYcvynGL6fLEVfao+XF3Tdyd+6zklDN68u3A/rRxcEfNRVAkApdohKqt251/AYKICy69BJZSi4Dy9S45IwCz52XEiScHQf0TVIqu/nYifvC711HYcjC4885EVzzThz0jBxpX4DAkAO78kqIdrZU7k/bnewPrmH92DAoJxJMZ16SxPa9/gLc2E1z++rt7GoLz3Rw6pk8gDtjrQPpnIcrifG0NHStWd1AkBn1Nw9mQ73h2ynpGZFrHEXTx5OLbKV6VUd8oxSxha0yffOVO50No4CDwhP09s2O0sCHLdDv6cV9A7ZQYQ83QWC";

        /**
         * debug 模式，开启后有详细的日志
         */
        Adapay.debug = false;

        /**
         * prodMode 模式，默认为生产模式，false可以使用mock模式
         */
        Adapay.prodMode = true;

        /**
         * 初始化商户配置，服务器启动前，必须通过该方式初始化商户配置完成
         * apiKey为prod模式的API KEY
         * mockApiKey为mock模式的API KEY
         * rsaPrivateKey为商户发起请求时，用于请求参数加签所需要的RSA私钥
         */
        String apiKey = "api_live_33ed81a1-8a90-4447-a22c-4012db7366cd";
        String mockApiKey = "api_test_18961037-e7a6-479e-8e69-582c90ef25d3";
        String rsaPrivateKey = rsaPri;
        MerConfig merConfig = new MerConfig();
        merConfig.setApiKey(apiKey);
        merConfig.setApiMockKey(mockApiKey);
        merConfig.setRSAPrivateKey(rsaPrivateKey);
        try {
            Adapay.initWithMerConfig(merConfig);
            String moneyString = "50";
            if (moneyString.contains(".")) {
                if (moneyString.indexOf(".") == moneyString.length() - 2) {
                    moneyString = moneyString + "0";
                } else if (moneyString.indexOf(".") == moneyString.length() - 1) {
                    moneyString = moneyString + "00";
                }

            } else {
                moneyString = moneyString + ".00";
            }
            String orderId = getOrderCode();
            //请求参数
            Map<String, Object> paymentParams = new HashMap<String, Object>();
            paymentParams.put("order_no", orderId);
            paymentParams.put("pay_amt", moneyString);
            paymentParams.put("app_id", "app_a762ad25-76b1-4a32-8ee0-9ad2fe32f4a0");
            paymentParams.put("pay_channel", "alipay");
            paymentParams.put("goods_title", "商城APP购物");
            paymentParams.put("goods_desc", "商城APP购物");
            paymentParams.put("description", "商城APP购物");
            paymentParams.put("notify_url", "http://47.104.95.141:8015/api/pay/huifu/callback");
            // paymentParams.put("div_members",  [{"amount":"0.05", "fee_flag":"Y", "member_id":"member_id_test"}]);
// 调用创建方法，获取 Payment对象_
            Map<String, Object> response = Payment.create(paymentParams);
            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(response));
            System.out.println("response--->" + JSON.toJSONString(response));
            if (jsonObject != null && !jsonObject.isEmpty()) {
                JSONObject jsonData = new JSONObject();
                jsonData.put("expend", jsonObject.getJSONObject("expend"));
                // balanceService.createTradeRecord(userId, orderId, money, PayType.XSPAY, 0);
                FsResponseGen.successData(jsonData);
            } else {
                FsResponseGen.failMsg("系统异常");
            }


        } catch (Exception e) {
            e.printStackTrace();
            FsResponseGen.failMsg("系统异常");
        }


//
//
//        String orderCode =System.currentTimeMillis()+"";
//         Map<String, Object> map = new HashMap<>();
//        map.put("userNo", "888112200001817");// 商户编号
//        map.put("productCode", "BANK_PAY_DAILY_ORDER");//产品类型
//        map.put("requestTime", DateUtils.formatDate(new Date())); // 交易请求时间
//        map.put("merchantOrderNo", orderCode);//商户订单号
//        map.put("receiverAccountNoEnc", "6230520330015785974"); // 6215682600004822193
//        map.put("receiverNameEnc", "李贤晓"); // 收款人雷钢
//        map.put("receiverAccountType", "201");//账户类型
//        map.put("paidAmount", "1"); //交易金额
//        map.put("currency", "201");//币种
//        map.put("isChecked", "202");//是否复核
//        map.put("paidDesc", "用户提现");//代付说明
//        map.put("paidUse", "207");//代付用途
//        map.put("callbackUrl", "http://baidu.com");//代付用途
//        try {
//            String respStr = HjWithdrawUtil.getHjResponse("02972f1b2f414e6fa621b05dee416c22", map);
//            Map<String, Object> httpResponseMap = (Map<String, Object>) JSONObject.parse(respStr);
//            Integer statusCode = (Integer) httpResponseMap.get("statusCode");
//            if (2001 == statusCode) {
////                return FsResponseGen.success();
//            } else if (2002 == statusCode) {
//                logger.error("受理失败:{}", respStr);
//             } else {
// //                return FsResponseGen.success();
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//            logger.error("withdraw err:{}", e.getMessage());
////            return FsResponseGen.failMsg("提现异常");
//        }
    }


    @Override
    public FsResponse xspayGetUserAccount(String xspayUserId, Integer count) {
        Q001TransForm q001TransForm = new Q001TransForm();
        q001TransForm.setTranCode("Q001");
        String merOrderId = xspayUserId + DateUtils.formatDate(new Date(), "yyyyMMddHHmmss") + count;
        q001TransForm.initCommonParams("Q001", configPay.getxSpay().getMerId(), merOrderId);
        q001TransForm.setSubmitUrl("https://ncount.hnapay.com/api/q001.htm");
        q001TransForm.setUserId(xspayUserId);
        try {
            Map<String, Object> result = XSpayService.getInstance().post(q001TransForm, Q001TransForm.verifyArr);
            if (Objects.isNull(result)) {
                return FsResponseGen.failMsg("查询失败");
            }
            if ("0000".equals(result.get("resultCode"))) {
                return FsResponseGen.successData(result);
            } else {
                return FsResponseGen.failMsg(result.get("errorMsg").toString());
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
            e.printStackTrace();
            return FsResponseGen.failMsg("查询异常");
        }
    }

    @Override
    public FsResponse xspayGetAccount() {
        Q001TransForm q001TransForm = new Q001TransForm();
        q001TransForm.setTranCode("Q001");
        q001TransForm.initCommonParams("Q001", configPay.getxSpay().getMerId(), null);
        q001TransForm.setSubmitUrl("https://ncount.hnapay.com/api/q001.htm");
        q001TransForm.setUserId(configPay.getxSpay().getMerId());
        try {
            Map<String, Object> result = XSpayService.getInstance().post(q001TransForm, Q001TransForm.verifyArr);
            if (Objects.isNull(result)) {
                return FsResponseGen.failMsg("查询失败");
            }
            if ("0000".equals(result.get("resultCode"))) {
                return FsResponseGen.successData(result);
            } else {
                return FsResponseGen.failMsg(result.get("errorMsg").toString());
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
            e.printStackTrace();
            return FsResponseGen.failMsg("查询异常");
        }
    }

    private FsResponse xspayTrans(User user, BigDecimal money) {
        T003TransForm t003TransForm = new T003TransForm();
        t003TransForm.setTranCode("T003");
        t003TransForm.initCommonParams("T003", configPay.getxSpay().getMerId(), null);
        t003TransForm.setSubmitUrl("https://ncount.hnapay.com/api/t003.htm");
        t003TransForm.setPayUserId(configPay.getxSpay().getMerId());
        t003TransForm.setReceiveUserId(user.getXspayuserid());
        t003TransForm.setTranAmount(String.valueOf(money));
        t003TransForm.setBusinessType("");
        try {
            Map<String, Object> result = XSpayService.getInstance().post(t003TransForm, T003TransForm.verifyArr);
            if (Objects.isNull(result)) {
                return FsResponseGen.failMsg("转账校验失败");
            }
            if ("0000".equals(result.get("resultCode"))) {
                return FsResponseGen.successData(result);
            } else {
                return FsResponseGen.failMsg(result.get("errorMsg").toString());
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
            e.printStackTrace();
            return FsResponseGen.failMsg("转账异常");
        }
    }

    @Override
    public FsResponse xspayUserTrans(String xsuserId, BigDecimal money) {
        T003TransForm t003TransForm = new T003TransForm();
        t003TransForm.setTranCode("T003");
        t003TransForm.initCommonParams("T003", configPay.getxSpay().getMerId(), null);
        t003TransForm.setSubmitUrl("https://ncount.hnapay.com/api/t003.htm");
        t003TransForm.setPayUserId(xsuserId);
        t003TransForm.setReceiveUserId(configPay.getxSpay().getMerId());
        t003TransForm.setTranAmount(String.valueOf(money));
        t003TransForm.setBusinessType("");
        try {
            Map<String, Object> result = XSpayService.getInstance().post(t003TransForm, T003TransForm.verifyArr);
            if (Objects.isNull(result)) {
                return FsResponseGen.failMsg("转账校验失败");
            }
            if ("0000".equals(result.get("resultCode"))) {
                return FsResponseGen.successData(result);
            } else {
                return FsResponseGen.failMsg(result.get("errorMsg").toString());
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
            e.printStackTrace();
            return FsResponseGen.failMsg("转账异常");
        }
    }

//    private List<UserBank> getXsBindUserBanks(Long userId) {
//        Example example = new Example(UserBank.class);
//        example.createCriteria().andEqualTo("userId", userId).andIsNotNull("xsbindcardagrno").andEqualTo("status", 0);
//        return userBankMapper.selectByExample(example);
//    }

    @Override
    public void hjPayNotify(Response req, HttpServletResponse resp) throws Exception {
        logger.debug("汇聚支付回调：。。。。。。。。");
        if (!"JS000000".equals(req.getBiz_code())) {
            logger.error("hjpay notify err:{}", req.getBiz_msg());
            return;
        }

        String signStr = HjPayUtil.getSortedString(req);
        System.out.println("待签名字符串：" + signStr);// 待签名字符串

        //待签名字符串
        //平台公钥验签
        //异步通知返回的sign
        String sign = req.getSign();

        boolean verify = verify(signStr, configPay.gethJpay().getPublicKey(), sign, false);
        if (verify) {
            JSONObject jsonObject = JSONObject.parseObject(req.getData());
            if (!"P1000".equals(jsonObject.getString("order_status"))) {
                logger.error("hjpay notify err order_status:{},order:{}", jsonObject.getString("order_status"), jsonObject.getString("mch_order_no"));
                return;
            }
            String orderId = jsonObject.getString("mch_order_no"); //获取后台通知的数据，其他字段也可用类似方式获取
            //查询交易记录
            try {
                UserTrade trade = balanceService.selectTradeByTradeNo(orderId);
                if (Objects.isNull(trade) || trade.getStatus() == 1) {
                    logger.debug("trade错误:{}", orderId);
                    return;
                }
                if (trade.getMoney().compareTo(new BigDecimal(jsonObject.getString("order_amount"))) != 0) {
                    logger.error("hjpay notify err money:{}", jsonObject.getString("mch_order_no"));
                    return;
                }

                BalanceType balanceType;
                String memo;
                if (trade.getType() == 0) {
                    memo = "汇聚支付充值到余额";
                    balanceType = BalanceType.ADD;

                    //金额入账
                    balanceService.update(trade.getUserId(), balanceType, trade.getMoney(), trade.getId(), memo);
                    pushService.sendServiceSingle(2, null, DateUtils.formatDate(trade.getCtime()), trade.getId(), trade.getUserId(), "充值成功", trade.getMoney(), "成功充值【" + trade.getMoney() + "】元", false);

                } else if (trade.getType() == 1) {
                    balanceType = BalanceType.ALIPAY_CREATE_PACKET;
                    memo = "汇聚支付充值创建红包";

                    //金额入账
                    balanceService.update(trade.getUserId(), balanceType, trade.getMoney(), trade.getId(), memo);
                    pushService.sendServiceSingle(2, null, DateUtils.formatDate(trade.getCtime()), trade.getId(), trade.getUserId(), "充值成功", trade.getMoney(), "成功充值【" + trade.getMoney() + "】元", false);
                }

                //交易记录状态更新
                balanceService.completeTrade(trade.getId());
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("hjpay notify err db err:{}", jsonObject.getString("mch_order_no"));
            }
        }

        logger.debug("汇聚支付接收后台通知结束");
    }

    @Override
    public void hjpayWithdrawNotify(WithdrawResponse req) {
        logger.debug("汇聚提现回调：。。。。。。。。");
        if (req.getStatus() != 204 && req.getStatus() != 205 && req.getStatus() != 208) {
            logger.error("hjpay withdraw notify not end status:{}", req.getStatus());
            return;
        }
        // 响应签名串
        String respSign = HjWithdrawUtil.getResponseSign(req);
        // 请求数据的加密签名
        String reqHmac = Md5_Sign.SignByMD5(respSign, configPay.gethJpay().getMd5Key());
        // 请求数据的加密签名
        String respHmac = req.getHmac();
        reqHmac = reqHmac.toUpperCase();
        respHmac = respHmac.toUpperCase();
        boolean isMatch = reqHmac.equals(respHmac);
        if (!isMatch) {
            logger.error("hjpay withdraw hmac fail:{},{},{}", respSign, reqHmac, JSONObject.toJSONString(req));
            return;
        }

        if (req.getStatus() == 204 || req.getStatus() == 208) {
            String[] ids = req.getMerchantOrderNo().split("_");
            Integer id = Integer.valueOf(ids[0]);
            balanceService.checkWithdrawForHj(id, 2, "提现异常，请联系客服处理");
        } else {
            String[] ids = req.getMerchantOrderNo().split("_");
            Integer id = Integer.valueOf(ids[0]);
            balanceService.checkWithdrawForHj(id, 1, null);
        }
        logger.debug("汇聚支付接收后台通知结束");
    }


    /**
     * 获取请求参数中所有的信息
     *
     * @param request
     * @return
     */
    private static Map<String, String> getAllRequestParam(final HttpServletRequest request) {
        Map<String, String> res = new HashMap<>();
        Enumeration<?> temp = request.getParameterNames();
        if (null != temp) {
            while (temp.hasMoreElements()) {
                String en = (String) temp.nextElement();
                String value = request.getParameter(en);
                res.put(en, value);
                //在报文上送时，如果字段的值为空，则不上送<下面的处理为在获取所有参数数据时，判断若值为空，则删除这个字段>
                //System.out.println("ServletUtil类247行  temp数据的键=="+en+"     值==="+value);
                if (null == res.get(en) || "".equals(res.get(en))) {
                    res.remove(en);
                }
            }
        }
        return res;
    }

    @Override
    public String alipayPre(Long userId, Integer tradeType, BigDecimal money) {


        logger.debug("支付宝预下单。。。。");

        //暂时订单号使用
        String out_trade_no = DateUtils.formatDate(new Date(), "yyyyMMddHHmmssSSS") + userId;
        //生成交易记录
        balanceService.createTradeRecord(userId, out_trade_no, money, PayType.ALIPAY, tradeType);

        // 获取配置文件中支付宝相关信息
        String aliPayGateway = "https://openapi.alipay.com/gateway.do";
        String signType = "RSA2";
        String alipayFormat = "json";
        String alipayCharset = "utf-8";

        AlipayClient alipayClient = new DefaultAlipayClient(aliPayGateway, configPay.getAlipay().getAppId(), configPay.getAlipay().getPrivateKey(), alipayFormat, alipayCharset, configPay.getAlipay().getAppPublicKey(), signType);
        AlipayTradeAppPayRequest alipayRequest = new AlipayTradeAppPayRequest();
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        //在body里存储跳转信息
        String redirect = configPay.getAlipay().getRedirectUrl();
        model.setBody("支付宝充值" + (StringUtils.isNotBlank(redirect) ? ("zf" + redirect) : ""));
        model.setSubject("支付宝充值");
        // 唯一订单号 根据项目中实际需要获取相应的
        model.setOutTradeNo(out_trade_no);
        // 支付超时时间（根据项目需要填写）
        model.setTimeoutExpress("10m");
        // 支付金额（项目中实际订单的需要支付的金额，金额的获取与操作请放在服务端完成，相对安全）
        model.setTotalAmount(NumberUtils.scale2HalfUp(money).toString());
        model.setProductCode("QUICK_MSECURITY_PAY");
        alipayRequest.setBizModel(model);
        // 支付成功后支付宝异步通知的接收地址url
        //alipayRequest.setNotifyUrl("http://47.56.123.244:8015/api/pay/alipay/notify");
        alipayRequest.setNotifyUrl(configPay.getAlipay().getNotifyUrl());

        AlipayTradeAppPayResponse alipayResponse = null;
        try {
            logger.debug("开始请求执行预支付接口。。。");
            logger.debug(JSON.toJSONString(alipayRequest));
            alipayResponse = alipayClient.sdkExecute(alipayRequest);
            logger.debug("请求结果:" + JSON.toJSONString(alipayResponse));
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }

        // 返回支付相关信息(此处可以直接将getBody中的内容直接返回，无需再做一些其他操作)
        return alipayResponse.getBody();
    }


    @Override
    public FsResponse transferAlipayAccount(String appOrderNO, String account, BigDecimal money) {


        //商户订单号

        //初始化客户端
        DefaultAlipayClient alipayClien = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", configPay.getAlipay().getAppId(), configPay.getAlipay().getPrivateKey(), "JSON", "UTF-8", configPay.getAlipay().getPublicKey(), "RSA2");

        //实例化提现请求
        AlipayFundTransToaccountTransferRequest request = new AlipayFundTransToaccountTransferRequest();

        //参数对象
        AlipayFundTransToaccountTransferModel model = new AlipayFundTransToaccountTransferModel();
        model.setOutBizNo(appOrderNO);
        model.setAmount(money.toString());
        model.setPayeeType("ALIPAY_LOGONID");
        //收款方账号
        model.setPayeeAccount(account);
        model.setRemark("APP提现");
        //绑定参数model
        request.setBizModel(model);
        try {
            //执行请求
            AlipayFundTransToaccountTransferResponse response = alipayClien.execute(request);


            if (response.isSuccess()) {
                //转账成功
                return FsResponseGen.success();
            } else {
                return FsResponseGen.failMsg(response.getCode() + "," + response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return FsResponseGen.failMsg("系统异常");
    }

    @Override
    public FsResponse sandPayApply(Long userId, BigDecimal money, String title) {

        String uid = "50517976";
        String price = String.valueOf(money.intValue());

        String nnorderid = getOrderCode();
        String notiUrl = "http://api.shiwu365.vip/api/pay/sandpay/callback";

        String suffix = "-B";


        String sn = MD5Util.getMD5Hex(uid + "#" + price + "#" + nnorderid + "#" + notiUrl + "#1111111111").toUpperCase();

        String url = "http://ppt.whhalin.cn/front/pay_halingh5/New/hnapay-new-quick.html?uid=50517976&nnorderid=" + nnorderid + "&price=" + price + "&notiUrl=" + notiUrl + "&sn=" + sn + "&suffix=" + suffix;
        //生成交易记录
        balanceService.createTradeRecord(userId, nnorderid, money, PayType.XSPAY, 0);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("sn", sn);
        jsonObject.put("nnorderid", nnorderid);

        return FsResponseGen.successData(jsonObject);


    }

    public static void main3(String[] args) {
        String uid = "50517976";
        String price = "100";

        String nnorderid = getOrderCode();
        String notiUrl = "http://api.shiwu365.vip/api/pay/sandpay/callback";

        String suffix = "-B";


        String sn = MD5Util.getMD5Hex(uid + "#" + price + "#" + nnorderid + "#" + notiUrl + "#1111111111").toUpperCase();

        String url = "http://ppt.whhalin.cn/front/pay_halingh5/New/hnapay-new-quick.html?uid=50517976&nnorderid=" + nnorderid + "&price=" + price + "&notiUrl=" + notiUrl + "&sn=" + sn + "&suffix=" + suffix;
        System.out.println(url);
        try {
            String result = HttpClient.doGet(url, new HashMap<>());
            System.out.println(result);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public FsResponse sandPayApply2(Long userId, BigDecimal money, String title) {
        try {
            ConfigurationManager.loadProperties(new String[]{"sandPayConfig"});
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            String orderId = getOrderCode();
            String data = getSendData(String.valueOf(userId), String.valueOf(money.multiply(new BigDecimal("100")).intValue()), orderId, title);
            //读取配置中公共URL
            String url = "https://cashier.sandpay.com.cn/";
            //  DynamicPropertyHelper.getStringProperty("sandpay.gateWay.url").get();
            //拼接本交易URL
            url += FastPayApiUtil.FASTPAY_INDEX;
            //创建HTTP辅助工具
            HttpUtil httpUtil = new HttpUtil();
            //通过辅助工具发送交易请求，并获取响应报文
            //生成交易记录
            balanceService.createTradeRecord(userId, orderId, money, PayType.XSPAY, 0);
            String result = httpUtil.sendGateWayPost(url, data, userId + "");
            if (result == null) {
                return FsResponseGen.failMsg("系统异常");
            } else {
                return FsResponseGen.successData(result);
            }
            // System.out.println(":" + result);
            // 验签签名

        } catch (Exception e) {
            e.printStackTrace();
            return FsResponseGen.failMsg("系统异常");
        }


    }

    @Override
    public FsResponse payconfig() {
        String payType = Optional.ofNullable(sysDictService.selectOne(DictKey.sys_pay_channel)).map(SysDict::getMemo).orElse("0");


        return FsResponseGen.successData(payType);

    }


    @Override
    public FsResponse huifuPayApply(Long userId, BigDecimal money, String title) {
        String rsaPri = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAKH2O7ZuCZjQTJccz07RU/+4edEmHYvERJmUelL9pdA5KEkywccXPKdGT0KwdewN8cMbUAD47sDDq09qhpjqpfGJCYR7xOpO57e4QwauU4fwbkJhG98+CTy9STPB7uTYENp7T159NQ4l3218eWUAzEtn0ZMOuWMN6u8E52tfPzMTAgMBAAECgYAMiNH2PG3htb03tLMWlny5vb0vwpNmzbnBaQxOf/LlOoczown8LoAzMe3Qa3e03R9oyiRW7u0LXhlT/BqOmxpch4F8ACFDfRDBLKljB4NZoijOfxAlonS+HOQ3J4Mgb6XLf1LOqNSMy7E2wbt6jzhNDZzv6i2lgcjJVWWVbgvxgQJBANUtM8dErBY0iUpW+i80qYavxSQB1dOsougmXnaV/+8ml0/beIQ7YJYaS5O0f1gqLgB++K2/5sbqxvb0k/gqkccCQQDCf0SCkdO02gianOwl9z1tqKbVzRSXD9pbE0j+G+zYcvynGL6fLEVfao+XF3Tdyd+6zklDN68u3A/rRxcEfNRVAkApdohKqt251/AYKICy69BJZSi4Dy9S45IwCz52XEiScHQf0TVIqu/nYifvC711HYcjC4885EVzzThz0jBxpX4DAkAO78kqIdrZU7k/bnewPrmH92DAoJxJMZ16SxPa9/gLc2E1z++rt7GoLz3Rw6pk8gDtjrQPpnIcrifG0NHStWd1AkBn1Nw9mQ73h2ynpGZFrHEXTx5OLbKV6VUd8oxSxha0yffOVO50No4CDwhP09s2O0sCHLdDv6cV9A7ZQYQ83QWC";

        /**
         * debug 模式，开启后有详细的日志
         */
        Adapay.debug = false;

        /**
         * prodMode 模式，默认为生产模式，false可以使用mock模式
         */
        Adapay.prodMode = true;

        /**
         * 初始化商户配置，服务器启动前，必须通过该方式初始化商户配置完成
         * apiKey为prod模式的API KEY
         * mockApiKey为mock模式的API KEY
         * rsaPrivateKey为商户发起请求时，用于请求参数加签所需要的RSA私钥
         */
        String apiKey = "api_live_33ed81a1-8a90-4447-a22c-4012db7366cd";
        String mockApiKey = "api_test_18961037-e7a6-479e-8e69-582c90ef25d3";
        String rsaPrivateKey = rsaPri;
        MerConfig merConfig = new MerConfig();
        merConfig.setApiKey(apiKey);
        merConfig.setApiMockKey(mockApiKey);
        merConfig.setRSAPrivateKey(rsaPrivateKey);
        try {
            Adapay.initWithMerConfig(merConfig);
            String moneyString = money.toString();
            if (moneyString.contains(".")) {
                if (moneyString.indexOf(".") == moneyString.length() - 2) {
                    moneyString = moneyString + "0";
                } else if (moneyString.indexOf(".") == moneyString.length() - 1) {
                    moneyString = moneyString + "00";
                }

            } else {
                moneyString = moneyString + ".00";
            }
            String orderId = getOrderCode();
            //请求参数
            Map<String, Object> paymentParams = new HashMap<String, Object>();
            paymentParams.put("order_no", orderId);
            paymentParams.put("pay_amt", moneyString);
            paymentParams.put("app_id", "app_a762ad25-76b1-4a32-8ee0-9ad2fe32f4a0");
            paymentParams.put("pay_channel", "alipay");
            paymentParams.put("goods_title", "商城APP购物");
            paymentParams.put("goods_desc", "商城APP购物");
            paymentParams.put("description", "商城APP购物");
            paymentParams.put("notify_url", "http://47.104.95.141:8015/api/pay/huifu/callback");
            // paymentParams.put("div_members",  [{"amount":"0.05", "fee_flag":"Y", "member_id":"member_id_test"}]);
// 调用创建方法，获取 Payment对象_
            Map<String, Object> response = Payment.create(paymentParams);
            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(response));
            //System.out.println("response--->"+ JSON.toJSONString(response));
            if (jsonObject != null && !jsonObject.isEmpty()) {
                JSONObject jsonData = new JSONObject();
                jsonData.put("expend", jsonObject.getJSONObject("expend"));
                balanceService.createTradeRecord(userId, orderId, money, PayType.XSPAY, 0);
                return FsResponseGen.successData(jsonData);
            } else {
                return FsResponseGen.failMsg("系统异常");
            }


        } catch (Exception e) {
            e.printStackTrace();
            return FsResponseGen.failMsg("系统异常");
        }


    }

    @Override
    public FsResponse sandPayApplyH5(Long userId, BigDecimal money, String clientIp) {
        String url = "https://openapi.duolabao.com/v1/customer/order/payurl/create";
        String customerNum = "10001116708945938441188";//商户编号
        String shopNum = "10001216708948815710694";//商户编号
        String machineNum = "10011029167171365002052";//商户编号
        String requestNum = getOrderCode();
        String amount = money.toString();
        String source = "API";
        String callbackUrl = "http://118.190.154.1:8015/api/pay/huifu/callback";
        JSONObject body = new JSONObject();
        body.put("customerNum", customerNum);
        body.put("shopNum", shopNum);
        body.put("machineNum", machineNum);
        body.put("requestNum", requestNum);
        body.put("amount", amount);
        body.put("source", source);
        body.put("callbackUrl", callbackUrl);

        String accessKey = "bf612157c7a747628171daac837454869d7e1140";


        String timestamp = String.valueOf(System.currentTimeMillis());
        String signString = "secretKey=bc34643a46d04bc3809a929f68d34105f38b4909" + "&timestamp=" + timestamp + "&path=/v1/customer/order/payurl/create" + "&body=" +
                body.toJSONString();
        String token = EncryptUtil.getSha1(signString);
        Map<String, String> headers = new HashMap<>();
        headers.put("accessKey", accessKey);
        headers.put("timestamp", timestamp);
        headers.put("token", token);

        String result = OKHttpUtil.httpPostJson(url, body.toJSONString(), headers);
        if (result != null) {
            JSONObject resJson = JSONObject.parseObject(result);
            if ("success".equals(resJson.getString("result"))) {
                JSONObject data = resJson.getJSONObject("data");
                String urlData = data.getString("url");
                if (urlData != null) {
                    JSONObject dataChild = new JSONObject();
                    dataChild.put("url", urlData);
                    balanceService.createTradeRecord(userId, requestNum, money, PayType.XSPAY, 0);

                    return FsResponseGen.successData(dataChild);
                }

            }
        }
//        System.out.println("result--->"+result);

        return FsResponseGen.failMsg("充值渠道错误~");

    }


    @Override
    public synchronized FsResponse sandPayCallBack(HttpServletRequest request, HttpServletResponse response) {
        JSONObject reqJson = (JSONObject) JSON.toJSON(getAllRequestParam(request));
        logger.error("====>打印===》2222" + reqJson.toJSONString());

        // {"nnorderid":"1025234028x7n6vcbz","price":"50","sn":"A72A3AA85F632DCC8197DD65D0DE5A40"}


        if (reqJson != null) {

            String nnorderid = reqJson.getString("nnorderid");
            String price = reqJson.getString("price");
            String sn = reqJson.getString("sn");
            String currentsn = MD5Util.getMD5Hex(price + "#" + nnorderid + "#1111111111").toUpperCase();
            if (!currentsn.equals(sn)) {
                return FsResponseGen.failMsg("禁用接口");
            }


            String orderId = nnorderid; //获取后台通知的数据，其他字段也可用类似方式获取
            //查询交易记录
            try {
                UserTrade trade = balanceService.selectTradeByTradeNo(orderId);
                if (Objects.isNull(trade) || trade.getStatus() == 1) {
                    logger.debug("trade错误:{}", orderId);
                    return null;
                }
                if (trade.getMoney().compareTo(new BigDecimal(price)) != 0) {
                    logger.error("hjpay notify err money:{}", orderId);
                    return null;
                }

                BalanceType balanceType;
                String memo;
                if (trade.getType() == 0) {
                    memo = "新生支付充值到余额";
                    balanceType = BalanceType.ADD;

                    //金额入账
                    balanceService.update(trade.getUserId(), balanceType, trade.getMoney(), trade.getId(), memo);
                    pushService.sendServiceSingle(2, null, DateUtils.formatDate(trade.getCtime()), trade.getId(), trade.getUserId(), "充值成功", trade.getMoney(), "成功充值【" + trade.getMoney() + "】元", false);

                } else if (trade.getType() == 1) {
                    balanceType = BalanceType.ALIPAY_CREATE_PACKET;
                    memo = "新生支付充值创建红包";

                    //金额入账
                    balanceService.update(trade.getUserId(), balanceType, trade.getMoney(), trade.getId(), memo);
                    pushService.sendServiceSingle(2, null, DateUtils.formatDate(trade.getCtime()), trade.getId(), trade.getUserId(), "充值成功", trade.getMoney(), "成功充值【" + trade.getMoney() + "】元", false);
                }

                //交易记录状态更新
                balanceService.completeTrade(trade.getId());
            } catch (Exception e) {
                e.printStackTrace();
            }


        }


        try {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("respCode", "000000");
            response.getWriter().print(jsonObject);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    public FsResponse huifuPayCallBack(HttpServletRequest request, HttpServletResponse response) {
        JSONObject reqJson = (JSONObject) JSON.toJSON(getAllRequestParam(request));
        logger.error("====>打印===》huifuPayCallBack" + reqJson.toJSONString());
        //{"requestNum":"1222204931gjtwjuq2","orderAmount":"10.00","bankRequestNum":"10031102212222049330494411885637","orderNum":"10021002212222049320514411887168","completeTime":"2022-12-22 20:49:56","bankOutTradeNum":"cc90aefa666f4ce49775336c8eedce2e","status":"SUCCESS"}

        if (reqJson != null) {


            String orderStatus = reqJson.getString("status");
            if ("SUCCESS".equals(orderStatus)) {

                String orderId = reqJson.getString("requestNum"); //获取后台通知的数据，其他字段也可用类似方式获取
                String money = reqJson.getString("orderAmount");
                //查询交易记录
                try {
                    UserTrade trade = balanceService.selectTradeByTradeNo(orderId);
                    if (Objects.isNull(trade) || trade.getStatus() == 1) {
                        logger.debug("trade错误:{}", orderId);
                        return null;
                    }
                    if (trade.getMoney().compareTo(new BigDecimal(money)) != 0) {
                        logger.error("hjpay notify err money:{}", orderId);
                        return null;
                    }

                    BalanceType balanceType;
                    String memo;
                    if (trade.getType() == 0) {
                        memo = "京东充值到余额";
                        balanceType = BalanceType.ADD;

                        //金额入账
                        balanceService.update(trade.getUserId(), balanceType, trade.getMoney(), trade.getId(), memo);
                        pushService.sendServiceSingle(2, null, DateUtils.formatDate(trade.getCtime()), trade.getId(), trade.getUserId(), "充值成功", trade.getMoney(), "成功充值【" + trade.getMoney() + "】元", false);

                    } else if (trade.getType() == 1) {
                        balanceType = BalanceType.ALIPAY_CREATE_PACKET;
                        memo = "京东充值到余额";

                        //金额入账
                        balanceService.update(trade.getUserId(), balanceType, trade.getMoney(), trade.getId(), memo);
                        pushService.sendServiceSingle(2, null, DateUtils.formatDate(trade.getCtime()), trade.getId(), trade.getUserId(), "充值成功", trade.getMoney(), "成功充值【" + trade.getMoney() + "】元", false);
                    }

                    //交易记录状态更新
                    balanceService.completeTrade(trade.getId());
                } catch (Exception e) {
                    e.printStackTrace();
                    logger.error("hjpay notify err db err:{}", reqJson.getString("orderCode"));
                }
            }


        }


        try {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("respCode", "000000");
            response.getWriter().print(jsonObject);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    public FsResponse bindCardAliPay(Long userId, UserBank bank) {
        Example example = new Example(UserBank.class);
        example.createCriteria().andEqualTo("bankNumber", bank.getBankNumber()).andEqualTo("userId", userId);
        UserBank exist = userBankMapper.selectOneByExample(example);
        if (Objects.nonNull(exist)) {
            if (exist.getStatus() == 1) {
                exist.setStatus(0);
                userBankMapper.updateByPrimaryKeySelective(exist);
                return FsResponseGen.successData("绑定成功");
            } else {
                return FsResponseGen.failMsg("该支付宝账号已存在");
            }
        }
        String orderCode = userId + System.currentTimeMillis() + "" + System.currentTimeMillis() + "1";
        bank.setHjbindcardordercode(orderCode);
        bank.setHjbindcardno(orderCode);
        bank.setStatus(0);
        if (Objects.nonNull(bank.getId())) {
            userBankMapper.updateByPrimaryKeySelective(bank);
        } else {
            userBankMapper.insertSelective(bank);
        }
        return FsResponseGen.successData("设置成功");
    }

    @Override
    public FsResponse bindCardWeChatPay(Long userId, UserBank bank) {
        Example example = new Example(UserBank.class);
        example.createCriteria().andEqualTo("bankNumber", bank.getBankNumber()).andEqualTo("userId", userId);
        UserBank exist = userBankMapper.selectOneByExample(example);
        if (Objects.nonNull(exist)) {
            if (exist.getStatus() == 1) {
                exist.setStatus(0);
                userBankMapper.updateByPrimaryKeySelective(exist);
                return FsResponseGen.successData("绑定成功");
            } else {
                return FsResponseGen.failMsg("该微信账号已存在");
            }
        }
        String orderCode = userId + System.currentTimeMillis() + "" + System.currentTimeMillis() + "1";
        bank.setHjbindcardordercode(orderCode);
        bank.setHjbindcardno(orderCode);
        bank.setStatus(0);
        if (Objects.nonNull(bank.getId())) {
            userBankMapper.updateByPrimaryKeySelective(bank);
        } else {
            userBankMapper.insertSelective(bank);
        }
        return FsResponseGen.successData("设置成功");
    }


    /**
     * 组报文
     */
    public String getSendData(String userId, String money, String orderId, String title) {
        // 数据域
        JSONObject dataJson = new JSONObject();
        long commentTime = System.currentTimeMillis();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        // time为转换格式后的字符串
        String time = simpleDateFormat.format(new Date(commentTime));

        // 报文体
        JSONObject bodyJson = new JSONObject();
        bodyJson.put("userId", userId); //交易日期/结算日期
        bodyJson.put("orderCode", orderId); //文件返回类型
        bodyJson.put("orderTime", time);
        int length = money.length();
        for (int i = 0; i < (12 - length); i++) {
            money = "0" + money;
        }
        bodyJson.put("totalAmount", money);
        bodyJson.put("subject", "充值消费");
        bodyJson.put("body", "充值消费");
        bodyJson.put("currencyCode", "156");
        bodyJson.put("notifyUrl", "http://api.shiwu365.vip/api/pay/sandpay/callback");


        // 报文头
        dataJson.put("head", getAgHeadJson("sandPay.fastPay.quickPay.index", "00000016"));
        dataJson.put("body", bodyJson);
        dataJson.put("extend", userId);
        String returnString = dataJson.toJSONString();
        return returnString;
    }

    /**
     * 组报文
     */
    public String getSendDataWithdraw(String userId, String money, String orderId, String cardNo, String name) {
        // 数据域
        //  JSONObject dataJson = new JSONObject();
        long commentTime = System.currentTimeMillis();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        // time为转换格式后的字符串
        String time = simpleDateFormat.format(new Date(commentTime));

        // 报文体
        JSONObject bodyJson = new JSONObject();
        bodyJson.put("version", "01"); //交易日期/结算日期
        bodyJson.put("productId", "00000004"); //文件返回类型
        bodyJson.put("tranTime", time);
        int length = money.length();
        for (int i = 0; i < (12 - length); i++) {
            money = "0" + money;
        }
        bodyJson.put("orderCode", orderId);
        bodyJson.put("tranAmt", money);
        bodyJson.put("accAttr", "0");
        bodyJson.put("accType", "4");

        bodyJson.put("currencyCode", "156");
        bodyJson.put("accNo", cardNo);
        bodyJson.put("accName", name);
        bodyJson.put("remark", "客户提现");


        // 报文头
        //  dataJson.put("head",  getAgHeadJson("sandPay.fastPay.quickPay.index", "00000016"));
//        dataJson.put("body", bodyJson);
//        dataJson.put("extend", userId);
        String returnString = bodyJson.toJSONString();
        return returnString;
    }

    /**
     * 组报文
     */
    public String getSendDataH5(String userId, String money, String orderId, String clientIp) {
        // 数据域
        JSONObject dataJson = new JSONObject();
        long commentTime = System.currentTimeMillis();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        // time为转换格式后的字符串
        String time = simpleDateFormat.format(new Date(commentTime));

        // 报文体
        JSONObject bodyJson = new JSONObject();
        bodyJson.put("orderCode", orderId); //文件返回类型
        int length = money.length();
        for (int i = 0; i < (12 - length); i++) {
            money = "0" + money;
        }
        bodyJson.put("totalAmount", money);
        bodyJson.put("subject", "test001");
        bodyJson.put("body", "吉尼斯降低分数");
        bodyJson.put("clientIp", clientIp);
        bodyJson.put("payMode", "sand_upsdk");
        bodyJson.put("notifyUrl", "http://api.shiwu365.vip/api/pay/sandpay/callback");


        // 报文头
        dataJson.put("head", getAgHeadJson("sandpay.trade.pay", "00000030"));
        dataJson.put("body", bodyJson);
        dataJson.put("extend", userId);
        String returnString = dataJson.toJSONString();
        return returnString;
    }

    /**
     * 获取支付报文头
     *
     * @return JSONObject
     * @Title: getAgHeadJson
     */
    public JSONObject getAgHeadJson(String method, String productId) {
        JSONObject headJson = new JSONObject();
        headJson.put("version", "1.0");
        headJson.put("method", method);
        headJson.put("productId", productId);
        headJson.put("accessType", "1");//商户接入类型
        headJson.put("mid", "6888802116942");
        headJson.put("plMid", "");//对应核心企业ID
        headJson.put("channelType", "08");
        headJson.put("reqTime", FastPayApiUtil.getCurTimestampStr());
        return headJson;
    }


    /**
     * 随机生成订单号
     *
     * @return
     */
    public static String getOrderCode() {

        String tradeNo = new SimpleDateFormat("MMddHHmmss").format(new Date())
                + RandomStringUtils.random(8, "abcdefghijklmnopqrstuvwxyz1234567890");
        return tradeNo;
    }
}
